/*
 * @Author: song
 * @Description:自动化创建Animator 辅助
 * @Date: 2024年04月15日 星期一 20:04:50
 * @Modify:
 */

#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.Animations;
using UnityEngine;

namespace SCore.Function.AutoAnimator
{
    public class AutoAnimator
    {
        /// <summary>
        /// 创建控制器
        /// </summary>
        /// <param name="createPath">路径</param>
        /// <returns></returns>
        public static AnimatorController CreateController(string createPath)
        {
            return AnimatorController.CreateAnimatorControllerAtPath(createPath);
        }

        /// <summary>
        /// 创建层
        /// </summary>
        /// <param name="controller">控制器</param>
        /// <param name="layerName">层名字</param>
        /// <returns></returns>
        public static AnimatorControllerLayer CreateLayer(AnimatorController controller, string layerName)
        {
            AutoAnimConfig.Instance._curCreatPos = 0;
            controller.AddLayer(layerName);
            var layer = controller.layers[^1];
            layer.stateMachine.entryPosition = AutoAnimConfig.Instance.GetPos();
            layer.stateMachine.exitPosition = AutoAnimConfig.Instance.GetPos();
            layer.stateMachine.anyStatePosition = AutoAnimConfig.Instance.GetPos();
            return layer;
        }

        /// <summary>
        /// 设置层
        /// </summary>
        /// <param name="layer">层</param>
        /// <param name="isKPass">是否支持iK</param>
        /// <param name="blendingMode">混合模式</param>
        /// <param name="avatarMask">遮罩</param>
        public static void SetUpLayer(AnimatorControllerLayer layer, bool isKPass,
            AnimatorLayerBlendingMode blendingMode, AvatarMask avatarMask = null)
        {
            layer.iKPass = true;
            layer.avatarMask = avatarMask;
            layer.blendingMode = blendingMode;
        }

        /// <summary>
        /// 添加参数
        /// </summary>
        /// <param name="controller">控制器</param>
        /// <param name="name">名字</param>
        /// <param name="animatorControllerParameterType">类型</param>
        public static void AddParams(AnimatorController controller, string name,
            AnimatorControllerParameterType parameterType)
        {
            controller.AddParameter(name, parameterType);
        }

        /// <summary>
        /// 添加ClipMotion
        /// </summary>
        /// <param name="layer">层</param>
        /// <param name="pos">位置</param>
        /// <param name="clip">动画片段</param>
        public static AnimatorState AddClipMotion(AnimatorControllerLayer layer, AnimationClip clip,
            string stateName)
        {
            AnimatorState state = layer.stateMachine.AddState(stateName, AutoAnimConfig.Instance.GetPos());
            state.motion = clip;
            state.name = stateName;
            return state;
        }


        /// <summary>
        /// 添加BlendTreeMotion
        /// </summary>
        /// <param name="layer">层</param>
        /// <param name="blendTree">blendTree</param>
        /// <param name="pos">位置</param>
        /// <param name="stateName">状态名字</param>
        public static AnimatorState AddBlendTreeMotion(AnimatorControllerLayer layer, BlendTree blendTree, Vector3 pos,
            string stateName)
        {
            AnimatorState state = layer.stateMachine.AddState(stateName, pos);
            state.motion = blendTree;
            state.name = stateName;
            return state;
        }

        public enum STransitionType
        {
            Any,
            Other
        }

        public struct SConditionParams
        {
            public string _conditionName;
            public AnimatorConditionMode _conditionMode;
        }

        public struct STransitionInfo
        {
            public bool _hasExit;
            public bool _hasFixedDuration;
            public float _duration;
            public float _exitTime;
            public float _offest;
        }

        public struct STransitionMap
        {
            public STransitionType _transitionType;
            public SConditionParams _conditionParams;
            public STransitionInfo _transitionInfo;
            public AnimatorState _aState;
            public AnimatorState _bState;

            public STransitionMap(bool hasExit, bool hasFixedDuration, float duration, float exitTime, float offest,
                AnimatorState aState, AnimatorState bState, string triggerName, string paramName,
                STransitionType transitionType, SConditionParams conditionParams, STransitionInfo transitionInfo)
            {
                _aState = aState;
                _bState = bState;
                _transitionType = transitionType;
                _conditionParams = conditionParams;
                _transitionInfo = transitionInfo;
            }
        }

        /// <summary>
        /// 添加条件连接
        /// </summary>
        /// <param name="layer">层</param>
        /// <param name="transitionMap">条件数据</param>
        public static void AddTransition(AnimatorControllerLayer layer,
            STransitionMap transitionMap)
        {
            AnimatorStateTransition stateTransition = null;
            if (transitionMap._transitionType == STransitionType.Any)
            {
                stateTransition = layer.stateMachine.AddAnyStateTransition(layer.stateMachine);
                stateTransition.destinationState = transitionMap._bState;
                if (!transitionMap._conditionParams._conditionName.IsNullOrEmpty())
                {
                    stateTransition.AddCondition(transitionMap._conditionParams._conditionMode, 0,
                        transitionMap._conditionParams._conditionName);
                }
            }
            else if (transitionMap._transitionType == STransitionType.Other)
            {
                var aState = transitionMap._aState;
                stateTransition = new AnimatorStateTransition();
                stateTransition.destinationState = transitionMap._bState;
                if (!transitionMap._conditionParams._conditionName.IsNullOrEmpty())
                {
                    stateTransition.AddCondition(transitionMap._conditionParams._conditionMode, 0,
                        transitionMap._conditionParams._conditionName);
                }

                aState.AddTransition(stateTransition);
            }

            if (stateTransition != null)
            {
                stateTransition.hasExitTime = transitionMap._transitionInfo._hasExit;
                stateTransition.hasFixedDuration = transitionMap._transitionInfo._hasFixedDuration;
                stateTransition.duration = transitionMap._transitionInfo._duration;
                stateTransition.exitTime = transitionMap._transitionInfo._exitTime;
                stateTransition.offset = transitionMap._transitionInfo._offest;
            }
        }

        /// <summary>
        /// 设置完保存
        /// </summary>
        /// <param name="createPath"></param>
        public static void Save(string createPath)
        {
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
            AssetDatabase.ImportAsset(createPath);
            AssetDatabase.Refresh();
            AssetDatabase.SaveAssets();
        }
    }
}
#endif